package bp.sys;

import bp.da.DBAccess;
import bp.da.DataTable;
import bp.da.DataType;
import bp.en.Row;
import bp.tools.Json;
import bp.web.WebUser;
import net.sf.json.JSONObject;

import java.util.Hashtable;

public class GloGenerDBSrc {

    ///#region A. 执行实例-获得结果
    /**
     执行Porc
     @param en
     @param paras 参数
     @return 执行结果
     */
    public static String ExecGenerDBSrc_SFProc(GenerDBSrc en, Hashtable paras) throws Exception {
        if (en.getDoWay().equals("None") == true)
        {
            return ""; // 可能未启用
        }

        if (en.getDBModel().equals("SFProc") == false)
        {
            throw new RuntimeException("err@当前不是执行的过程，无法返回结果. DBModel=" + en.getDBModel());
        }

        if (paras == null)
        {
            paras = new Hashtable();
        }

        if (en.getDoWay().equals("SelfSQL") == true)
        {
            String doc = en.getDoc();
            doc = Glo.DealExp(doc, paras);

            //   doc = bp.da.DataType.DealSQLExpHT(doc, paras);
            SFDBSrc dbsrc = new SFDBSrc(en.getDBSrc());
            int i = dbsrc.RunSQL(doc);
            return "info@执行成功,影响数据" + i + ".";
        }

        if (en.getDoWay().equals("SelfWebApiGet") == true)
        {
            return ExecGenerDBSrc_SFTableSearch_SelfWebApiGet(en, paras);
        }

        if (en.getDoWay().equals("SelfWebApiPost") == true)
        {
            return ExecGenerDBSrc_SFTableSearch_SelfWebApiPost(en, paras);
        }

        if (en.getDoWay().equals("SFProc") == true)
        {
            SFProc porc = new SFProc(en.getDoc());
            return porc.Exec(paras);
        }

        if (en.getDoWay().equals("EventBase") == true)
        {
            // throw new Exception("err@未实现,对类的解析:" + en.getDoc());
            //// 获取事件类.
            String evName = en.getDoc();
            bp.sys.base.EventBase ev = null;
            try
            {
                ev = bp.en.ClassFactory.GetEventBase(evName);
            }
            catch (RuntimeException ex)
            {
                throw new RuntimeException("@事件名称:" + evName + "拼写错误，或者系统不存在。说明：事件所在的类库必须是以BP.开头，并且类库的BP.xxx.dll。");
            }
            if (ev == null)
            {
                throw new RuntimeException("@事件名称:" + evName + "拼写错误，或者系统不存在。说明：事件所在的类库必须是以BP.开头，并且类库的BP.xxx.dll。");
            }

            Row myrow = new Row();
            for (Object key : paras.keySet())
            {
                myrow.put((String) key, paras.get(key));
            }
            //开始执行.
            ev.setSysPara(myrow);
            // ev.HisEn = en;
            ev.Do();
            String str = ev.SucessInfo;
            if (str.contains("err@") == true)
            {
                throw new RuntimeException(str);
            }
            return str;
        }

        if (en.getDoWay().equals("BuessUnit") == true)
        {
            BuessUnitBase enBuesss = bp.sys.base.Glo.GetBuessUnitEntityByEnName(en.getDoc());
            if (enBuesss == null)
            {
                throw new RuntimeException("err@没有实例化业务单元实体:[" + en.getDoc() + "]请检查，该类是否移除? ");
            }
            // enBuesss.HisSFDSrc = mysrc;
            enBuesss.BodyDoc = Json.ToJson(paras);
            //enBuesss.HeardDoc = headerData;
            Object tempVar = enBuesss.DoIt();
            String val2 = tempVar instanceof String ? (String)tempVar : null;
            return val2;
        }

        throw new RuntimeException("err@没有判断的数据：" + en.getDoWay());
    }
    ///#endregion B. 执行实例-获得结果.

// #region B. 执行实例获得数据源.

    /// <summary>
    /// 获得
    /// </summary>
    /// <param name="en"></param>
    /// <param name="paras"></param>
    /// <returns></returns>
    public static DataTable ExecGenerDBSrc_SFTableSearch(GenerDBSrc en, Hashtable paras) throws Exception {
        if (en.getDoWay().equals("None") == true)
            return new DataTable(); // 可能未启用

        if (en.getDBModel().equals("SFProc") == true)
            throw new Exception("err@当前是过程，不能返回 DataTable.");

        if (paras == null) paras = new Hashtable();

        String data = "";
        if (en.getDoWay().equals("SelfSQL") == true)
        {
            String doc = en.getDoc();
            doc = Glo.DealExp(doc, paras);
            SFDBSrc dbsrc = new SFDBSrc(en.getDBSrc());
            return dbsrc.RunSQLReturnTable(doc);
        }

        if (en.getDoWay().equals("SelfWebApiGet") == true)
        {
            String data1 = ExecGenerDBSrc_SFTableSearch_SelfWebApiGet(en, paras);
            return bp.tools.Json.ToDataTable(data1);
        }

        if (en.getDoWay().equals("SelfWebApiPost") == true)
        {
            String data2 = ExecGenerDBSrc_SFTableSearch_SelfWebApiPost(en, paras);
            return bp.tools.Json.ToDataTable(data2);
        }

        if (en.getDoWay().equals("SearchDBSrc") == true)
        {
            SFSearch sfSearch = new SFSearch(en.getDoc());
            return sfSearch.GenerHisDataTable(paras);
        }

        if (en.getDoWay().equals("SFTableDBSrc") == true)
        {
            SFTable table = new SFTable(en.getDoc());
            return table.GenerHisDataTable(paras);
        }

        // 静态的数据.
        if (en.getDoWay().equals("StaticData") == true)
        {
            String doc = en.getDoc();
            data = Glo.DealSQLExpHT(doc, paras);
        }
        throw new Exception("err@没有判断的数据");
    }
    public static ResultObj GenerDBSrc_ResultObj(GenerDBSrc en, Hashtable paras)
    {
        ResultObj resultObj = new ResultObj();
        try
        {
            DataTable dt = ExecGenerDBSrc_SFTableSearch(en, paras);

            String json = bp.tools.Json.ToJson(dt);
            resultObj.data = json;
            resultObj.code = 200;

            return resultObj;
        }
        catch (Exception ex)
        {
            resultObj.code = 500;
            resultObj.message = "编号:No=" + en.getMyPK() + ",异常信息:err:" + ex.getMessage();
            return resultObj;
        }
    }
    public static ResultObj GenerDBSrc_ResultObj(String no, Hashtable paras) throws Exception {
        GenerDBSrc en = new GenerDBSrc(no);
        return GenerDBSrc_ResultObj(en, paras);
    }
    private static String ExecGenerDBSrc_SFTableSearch_SelfWebApiGet(GenerDBSrc en, Hashtable paras) throws Exception {

        String url = en.GetValByKey("Url").toString();
        url = Glo.DealExp(url, paras);

        SFDBSrc src = new SFDBSrc(en.getDBSrc());
        url = src.getConnString() + "/" + url;
        url = url.replace("\\\\", "\\");
        url = url.replace("\\\\", "\\");
        
        if (url.toLowerCase().indexOf("token") == -1) {
            if (url.contains("?")) {
                url += "&Token=" + WebUser.getToken();
            } else {
                url += "?Token=" + WebUser.getToken();
            }
        }

        String data = DataType.ReadURLContext(url);
        if(data.startsWith("err@"))
            throw new RuntimeException(data);
        try{
            JSONObject jsonObject = JSONObject.fromObject(data);
            ResultObj obj = new ResultObj();
            obj.code = jsonObject.getInt("code"); // 200=执行成功, 404=配置错误，500=执行错误.
            obj.message = jsonObject.getString("message");
            obj.data =jsonObject.getString("data");
            if(obj.code == 200)
                return obj.data;
            throw new RuntimeException(obj.message+":"+obj.data);
        }catch(Exception ex){
            return data;
        }
    }
    private static String ExecGenerDBSrc_SFTableSearch_SelfWebApiPost(GenerDBSrc en, Hashtable paras) throws Exception {
        String url = en.getDoc();
        url = Glo.DealExp(url, paras);

        SFDBSrc src = new SFDBSrc(en.getDBSrc());
        url = src.getConnString() + "/" + url;
        url = url.replace("\\\\", "\\");
        url = url.replace("\\\\", "\\");
        if (url.toLowerCase().indexOf("token") == -1)
            url += "&Token=" + WebUser.getToken();

        String body = Glo.DealExp(en.getBodyDoc(), paras);
        String head = Glo.DealExp(en.getHeadDoc(), paras);

        ResultObj data = bp.en.OverrideFile.Data_WebApi_GenerStandReturnObj("Post", url, body, head);
        if(data.code == 200)
            return data.data;
        throw new Exception(data.message + " " + data.data);

    }
 //#endregion B.执行实例获得数据源.
 //#region C.初始化数据
    /// <summary>
    /// 获得数据源实体,根据markID,dbModel,实体主键.
    /// </summary>
    /// <param name="markID"></param>
    /// <param name="dbModel"></param>
    /// <param name="pkVal"></param>
    /// <returns></returns>
    /// <exception cref="Exception"></exception>
 public static GenerDBSrc GenerDBSrc_InitData(String markID, String dbModel, String pkVal) throws Exception {
     //定义变量.
     String objPKVal1 = ""; //操作对象的主键值1(一级对象), PageID,

     GenerDBSrc en = new GenerDBSrc();
     en.SetValByKey("MarkID", markID);
     en.SetValByKey("DoWay", "None");
     en.SetValByKey("DBModel", dbModel); //数据模式.
     en.SetValByKey("RefPKVal", pkVal); //关联的主键.

     ///#region 检查是否是1级对象
     //检查是否是1级对象? 表单:
     objPKVal1 = DBAccess.RunSQLReturnStringIsNull("SELECT No FROM Sys_MapData WHERE No='" + pkVal + "'", null);
     if (objPKVal1 != null)
     {
         en.setMyPK("Frm." + pkVal + "." + markID);
         if (en.RetrieveFromDBSources() == 0)
         {
             en.SetValByKey("ObjModel", "Frm"); //模式.
             en.SetValByKey("FrmID", pkVal);
             en.SetValByKey("OperID1", pkVal);
             en.Insert();
         }
         return en;
     }

     //报表:
     objPKVal1 = DBAccess.RunSQLReturnStringIsNull("SELECT No FROM Sys_Rpt WHERE No='" + pkVal + "'", null);
     if (objPKVal1 != null)
     {
         en.setMyPK("Rpt" + pkVal + "." + markID);
         if (en.RetrieveFromDBSources() == 0)
         {
             en.SetValByKey("ObjModel", "Rpt"); //模式.
             en.SetValByKey("RptID", pkVal);
             en.SetValByKey("OperID1", pkVal);
             en.Insert();
         }
         return en;
     }

     //流程:
     objPKVal1 = DBAccess.RunSQLReturnStringIsNull("SELECT No FROM WF_Flow WHERE No='" + pkVal + "'", null);
     if (objPKVal1 != null)
     {
         en.setMyPK("Flow." + pkVal + "." + markID);
         if (en.RetrieveFromDBSources() == 0)
         {
             en.SetValByKey("ObjModel", "Flow"); //模式.
             en.SetValByKey("FlowNo", pkVal);
             en.SetValByKey("OperID1", pkVal);
             en.Insert();
         }
         return en;
     }
     ///#endregion 检查是否是1级对象

     ///#region 检查是否是2级对象
     //节点:
     if (DataType.IsNumStr(pkVal) == true)
     {
         objPKVal1 = DBAccess.RunSQLReturnStringIsNull("SELECT FK_Flow FROM WF_Node WHERE NodeID='" + pkVal + "'", null);
         if (objPKVal1 != null)
         {
             en.setMyPK("Node." + pkVal + "." + markID);
             if (en.RetrieveFromDBSources() == 0)
             {
                 en.SetValByKey("ObjModel", "Node"); //模式.
                 en.SetValByKey("NodeID", pkVal);
                 en.SetValByKey("OperID1", objPKVal1);
                 en.SetValByKey("OperID1", pkVal);
                 en.Insert();
             }
             return en;
         }
     }
     //字段:
     objPKVal1 = DBAccess.RunSQLReturnStringIsNull("SELECT FK_MapData FROM Sys_MapAttr WHERE MyPK='" + pkVal + "'", null);
     if (objPKVal1 != null)
     {
         en.setMyPK("Frm." + pkVal + "." + markID);
         if (en.RetrieveFromDBSources() == 0)
         {
             en.SetValByKey("ObjModel", "Frm"); //模式.
             en.SetValByKey("FrmID", objPKVal1);
             en.SetValByKey("OperID1", pkVal);
             en.Insert();
         }
         return en;
     }
     //窗口:
     objPKVal1 = DBAccess.RunSQLReturnStringIsNull("SELECT PageID FROM GPM_WindowTemplate WHERE No='" + pkVal + "'", null);
     if (objPKVal1 != null)
     {
         en.setMyPK("Rpt." + objPKVal1 + "." + pkVal + "." + markID);
         if (en.RetrieveFromDBSources() == 0)
         {
             en.SetValByKey("ObjModel", "Rpt"); //模式.
             en.SetValByKey("RptID", objPKVal1);
             en.SetValByKey("OperID1", pkVal);
             en.Insert();
         }
         return en;
     }

     //MapExt:
     MapExt me = new MapExt();
     me.setMyPK(pkVal);
     if (me.RetrieveFromDBSources() == 1)
     {
         if (me.getExtModel().equals("Pop") == true || me.getExtModel().equals("Cascader") == true)
         {
             // AttrOfOper 是字段的 KeyOfEn.
             en.setMyPK("Frm." + me.getFrmID() + "_" + me.getAttrOfOper() + "." + markID);
             if (en.RetrieveFromDBSources() == 0)
             {
                 en.SetValByKey("ObjModel", "Frm"); //模式.
                 en.SetValByKey("FrmID", me.getFrmID());
                 en.SetValByKey("OperID1", me.getFrmID() + "_" + me.getAttrOfOper());
                 en.SetValByKey("OperID2", me.getAttrOfOper());
                 en.Insert();
             }
             return en;
         }

         //控件-填充.
         if (me.getExtModel().equals("FullDataDtl") == true
                 || me.getExtModel().equals("ActiveDDL") == true
                 || me.getExtModel().equals("DDLFullCtrl") == true
                 || me.getExtModel().equals("TBFullCtrl") == true
                 || me.getExtModel().equals("AutoFullDLL") == true)
         {
             // AttrOfOper 是字段的 KeyOfEn.
             if(markID.equals("FullDataBody") || markID.equals("TBFullCtrl") || DataType.IsNullOrEmpty(me.getTag1()))
                 en.setMyPK("Frm." + me.getFrmID() + "_" + me.getAttrOfOper()  + "." + markID);
             else
                 en.setMyPK("Frm." + me.getFrmID() + "_" + me.getAttrOfOper() + "." + me.getTag1() + "." + markID);
             if (en.RetrieveFromDBSources() == 0)
             {
                 en.SetValByKey("ObjModel", "Frm"); //模式.
                 en.SetValByKey("FrmID", me.getFrmID());
                 en.SetValByKey("OperID1", me.getAttrOfOper());
                 en.SetValByKey("OperID2", me.getTag1());
                 en.Insert();
             }
             return en;
         }
         if (me.getExtModel().equals("FullDataDDL") == true || me.getExtModel().equals("FullDataAth") == true)
         {
             // AttrOfOper 是字段的 KeyOfEn.
             en.setMyPK("Frm." + me.getFrmID() + "_" + me.getAttrOfOper() + "." + me.getTag1() + "." + markID);
             if (en.RetrieveFromDBSources() == 0)
             {
                 en.SetValByKey("ObjModel", "Frm"); //模式.
                 en.SetValByKey("FrmID", me.getFrmID());
                 en.SetValByKey("OperID1", me.getAttrOfOper());
                 en.SetValByKey("OperID2", me.getTag1());
                 en.Insert();
             }
             return en;
         }

         throw new RuntimeException("err@没有解析的类型,请增加GloGenerDBSrc:" + me.getExtModel());

     }
     ///#endregion 检查是否是1级对象
     FrmEvent frmEvent = new FrmEvent();
     frmEvent.setMyPK(pkVal);
     if (frmEvent.RetrieveFromDBSources() == 1)
     {
         if (frmEvent.getNodeID() != 0)
         {
             en.setMyPK("Node." + frmEvent.getNodeID() + "." + markID);
             if (en.RetrieveFromDBSources() == 0)
             {
                 en.SetValByKey("ObjModel", "Node"); //模式.
                 en.SetValByKey("FlowNo", frmEvent.getFlowNo());
                 en.SetValByKey("NodeID", frmEvent.getNodeID());
                 en.SetValByKey("OperID1", markID);
                 en.Insert();
             }
             return en;
         }

         if (DataType.IsNullOrEmpty(frmEvent.getFlowNo()) == false)
         {
             en.setMyPK("Flow." + frmEvent.getFlowNo() + "." + markID);
             if (en.RetrieveFromDBSources() == 0)
             {
                 en.SetValByKey("ObjModel", "Flow"); //模式.
                 en.SetValByKey("FlowNo", frmEvent.getFlowNo());
                 en.SetValByKey("OperID1", markID);
                 en.Insert();
             }
             return en;
         }

         if (DataType.IsNullOrEmpty(frmEvent.getFrmID()) == false)
         {
             en.setMyPK("Frm." + frmEvent.getFrmID() + "." + markID);
             if (en.RetrieveFromDBSources() == 0)
             {
                 en.SetValByKey("ObjModel", "Frm"); //模式.
                 en.SetValByKey("FrmID", frmEvent.getFrmID());
                 en.SetValByKey("OperID1", markID);
                 en.Insert();
             }
             return en;
         }
     }

     // 检查是条件表达式.
     String sql = "SELECT FK_Node,FK_Flow,ToNodeID,FrmID,CondType,MyPK FROM WF_Cond WHERE MyPK='" + pkVal + "' ";
     DataTable dt = DBAccess.RunSQLReturnTable(sql);
     if (dt.Rows.size() == 1)
     {
         String myPK = dt.Rows.get(0).getValue("MyPK") instanceof String ? (String)dt.Rows.get(0).getValue("MyPK") : null;
         String flowNo = dt.Rows.get(0).getValue("FK_Flow") instanceof String ? (String)dt.Rows.get(0).getValue("FK_Flow") : null;
         String nodeID = dt.Rows.get(0).getValue("FK_Node") instanceof String ? (String)dt.Rows.get(0).getValue("FK_Node") : null;
         String toNodeID = dt.Rows.get(0).getValue("ToNodeID") instanceof String ? (String)dt.Rows.get(0).getValue("ToNodeID") : null;
         int condType = Integer.parseInt(dt.Rows.get(0).getValue("CondType").toString());
         //方向条件=2.流程完成条件=1, 抄送=4 , 启动子流程=3. 节点完成条件=0
         if (condType == 2 || condType == 1 || condType == 4 || condType == 3 || condType == 0)
         {
             en.setMyPK("Node." + myPK + "." + markID);
             if (en.RetrieveFromDBSources() == 0)
             {
                 en.SetValByKey("ObjModel", "Node"); //模式.
                 en.SetValByKey("NodeID", nodeID);
                 en.SetValByKey("FlowNo", flowNo);
                 en.Insert();
             }
             return en;
         }
     }

     throw new RuntimeException("err@没有判断模式:PKVal:" + pkVal + ",DBModel:" + dbModel + ",MarkID:" + markID);
 }
    public static void InitGenerDBSrc_SelfSQL(String objID, String markID, String dbModel, String sql) throws Exception {
        InitGenerDBSrc(objID, dbModel, "SelfSQL", markID, "local", sql);
    }
    public static void InitGenerDBSrc_SFTable(String objID, String markID, String dbModel, String tableID) throws Exception {
        InitGenerDBSrc(objID, dbModel, "SFTableDBSrc", markID, "local", tableID);
    }

    public static void InitGenerDBSrc(String pkVal, String dbModel, String doWay, String markID, String dbSrc, String doc, String bodyDoc) throws Exception {
        InitGenerDBSrc(pkVal, dbModel, doWay, markID, dbSrc, doc, bodyDoc, "");
    }

    public static void InitGenerDBSrc(String pkVal, String dbModel, String doWay, String markID, String dbSrc, String doc) throws Exception {
        InitGenerDBSrc(pkVal, dbModel, doWay, markID, dbSrc, doc, "", "");
    }

      public static void InitGenerDBSrc(String pkVal, String dbModel, String doWay, String markID, String dbSrc, String doc, String bodyDoc, String headDoc) throws Exception {
        GenerDBSrc en = GloGenerDBSrc.GenerDBSrc_InitData(markID, dbModel, pkVal);

        //属于单个属性的,都可以放入Doc 字段里.
        if (doWay.equals("SelfSQL") || doWay.equals("SFProc") || doWay.equals("BuessUnit") || doWay.equals("EventBase") || doWay.equals("StaticData") || doWay.equals("SearchDBSrc"))
        {
            en.SetValByKey("DoWay", doWay); //内容.
            en.SetValByKey("DBModel", dbModel);
            en.SetValByKey("DBSrc", dbSrc);
            en.SetValByKey("Doc", doc); //内容.
            en.Update();
        }

        // 接口模式.
        if (doWay.equals("SelfWebApiGet") || doWay.equals("SelfWebApiPost"))
        {

            en.SetValByKey("DoWay", doWay); //内容.
            en.SetValByKey("DBModel", dbModel);
            en.SetValByKey("DBSrc", dbSrc);

            en.SetValByKey("Doc", doc); //内容.
            en.SetValByKey("BodyDoc", bodyDoc);
            en.SetValByKey("HeadDoc", headDoc);
            en.Update();
        }
    }
    ///#endregion C.初始化数据


}